package com.ciaojian.store.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.ciaojian.core.constant.RedisConstant;
import com.ciaojian.core.enums.business.OrderOrderTypeEnum;
import com.ciaojian.core.enums.business.OrderStatusEnum;
import com.ciaojian.core.model.Order;
import com.ciaojian.core.model.StoreFirstCost;
import com.ciaojian.core.model.vo.FeesetCostVo;
import com.ciaojian.core.model.vo.SalesProfitVo;
import com.ciaojian.core.model.vo.WorkerCostVo;
import com.ciaojian.core.util.*;
import com.ciaojian.store.model.bo.OperationMemberOrderBO;
import com.ciaojian.store.model.bo.OperationOrderBO;
import com.ciaojian.store.model.query.OperationOrderQuery;
import com.ciaojian.store.model.vo.OperationMemberOrderVO;
import com.ciaojian.store.model.vo.OperationOrderVO;
import com.ciaojian.store.service.MemberOrderServiceImpl;
import com.ciaojian.store.service.OrderServiceImpl;
import com.ciaojian.store.service.StoreFirstCostServiceImpl;
import io.swagger.annotations.*;
import org.apache.ibatis.annotations.Param;
import org.springframework.boot.autoconfigure.cache.CacheProperties;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.util.Assert;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.spring.web.json.Json;

import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;


/**
 * @author Atlakyn
 */
@Api(tags = "订单")
@RestController
@RequestMapping("/order")
public class OrderController {
    @Resource
    private OrderServiceImpl orderService;
    @Resource
    private MemberOrderServiceImpl memberOrderService;
    @Resource
    private StoreFirstCostServiceImpl storeFirstCostService;

    @ApiOperation("每日销售额")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "storeId", value = "门店ID", paramType = "query"),
            @ApiImplicitParam(name = "beginDate", value = "开始时间", paramType = "query"),
            @ApiImplicitParam(name = "endDate", value = "结束时间", paramType = "query")
    })
    @GetMapping("sales-day")
    public Result salesOfDay(@NotNull(message = "门店Id不能为空") Integer storeId,
                             @NotNull(message = "开始时间不能为空") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date beginDate,
                             @NotNull(message = "结束时间不能为空") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date endDate) {
        return Result.ok(orderService.getBaseMapper().sumPayTotalByStoreIdEveryDay(storeId, beginDate, endDate));
    }

    @ApiOperation("每月销售额")
    @ApiImplicitParam(name = "storeId", value = "门店ID", paramType = "query")
    @GetMapping("/sales-month")
    public Result salesOfMonth( Integer storeId,
                               @DateTimeFormat(pattern = "yyyy-MM") Date beginDate,
                               @DateTimeFormat(pattern = "yyyy-MM") Date endDate) {

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(endDate);
        calendar.add(Calendar.MONTH, + 1);
        calendar.add(Calendar.MINUTE, - 1);
        endDate = calendar.getTime();
        return Result.ok(orderService.getBaseMapper().sumPayTotalByStoreIdEveryMonth(storeId, beginDate,
                endDate));
    }

    @ApiImplicitParam(name = "storeId", value = "门店ID", paramType = "query")
    @GetMapping("/sales-month1")
    public Result salesOfMonth1(@NotNull(message = "门店Id不能为空") Integer storeId) {
        return Result.ok(orderService.getBaseMapper().sumPayTotalByStoreIdEveryMonth1(storeId));
    }

    @ApiOperation("投资回报")
    @ApiImplicitParam(name = "storeId", value = "门店ID", paramType = "query")
    @GetMapping("/invest-back")
    public Result investAndBack(@NotNull(message = "门店Id不能为空") Integer storeId) {
        LambdaQueryWrapper<StoreFirstCost> lambdaQueryWrapper = new LambdaQueryWrapper<StoreFirstCost>()
                .eq(StoreFirstCost::getStoreId, storeId);
        Assert.notNull(new StoreFirstCost().selectOne(lambdaQueryWrapper), "查询失败");
        return Result.ok(storeFirstCostService.investAndBack(storeId));
    }

    @ApiOperation("订单销售额")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "storeId", value = "门店ID", paramType = "query"),
            @ApiImplicitParam(name = "beginDate", value = "开始时间", paramType = "query"),
            @ApiImplicitParam(name = "endDate", value = "结束时间", paramType = "query")
    })
    @GetMapping("/sales")
    public Result sales(@NotNull(message = "开始时间不能为空") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date beginDate,
                        @NotNull(message = "结束时间不能为空") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date endDate,
                        @NotNull(message = "门店ID不能为空") Integer storeId) {
        // 剪发订单
        BigDecimal normalOrder = orderService.getBaseMapper().sumPayTotalByStoreIdAndOrderTypeBetweenBeginDateAndEndDate(storeId,
                OrderOrderTypeEnum.NORMAL,
                beginDate,
                endDate);
        // 美团订单
        BigDecimal meituanOrder = orderService.getBaseMapper().sumPayTotalByStoreIdAndOrderTypeBetweenBeginDateAndEndDate(storeId,
                OrderOrderTypeEnum.MEITUAN,
                beginDate,
                endDate);
        // 次卡订单
        BigDecimal cikaOrder = orderService.getBaseMapper().sumPayTotalByStoreIdAndOrderTypeBetweenBeginDateAndEndDate(storeId,
                OrderOrderTypeEnum.COUPON_PACKAGE,
                beginDate,
                endDate);
        Map<String, BigDecimal> resultMap = new HashMap<>(3);
        resultMap.put("normalOrder", normalOrder);
        resultMap.put("meituanOrder", meituanOrder);
        resultMap.put("cikaOrder", cikaOrder);
        return Result.ok(resultMap);
    }

    @ApiOperation("门店订单数")
    @ApiImplicitParam(name = "id", value = "门店 id", defaultValue = "7")
    @GetMapping("/{id}/numOfEveryday")
    public Result orderNum(@PathVariable("id") Integer id,
                           @DateTimeFormat(pattern = "yyyy-MM-dd") Date startDate,
                           @DateTimeFormat(pattern = "yyyy-MM-dd") Date endDate) {
        Assert.notNull(startDate, "请选择开始时间");
        Assert.notNull(endDate, "请选择结束时间");

        return Result.ok(orderService.getNumOfEveryday(id, startDate, endDate));
    }

    @ApiOperation("客数比例")
    @GetMapping("/{id}/count")
    public Result customerCount(@PathVariable("id") Integer id,
                                @DateTimeFormat(pattern = "yyyy-MM-dd") Date startDate,
                                @DateTimeFormat(pattern = "yyyy-MM-dd") Date endDate) {
        Assert.notNull(startDate, "请选择开始时间");
        Assert.notNull(endDate, "请选择结束时间");

        return Result.ok(orderService.countCustomer(id, startDate, endDate));
    }

    @ApiOperation("查询订单")
    @ApiResponses({
            @ApiResponse(response = OperationOrderVO.class, code = 200, message = "剪发订单返回数据"),
            @ApiResponse(response = OperationMemberOrderVO.class, code = 200, message = "会员订单返回数据")
    })
    @GetMapping("/operation")
    public Result all(@Validated OperationOrderQuery queryParam) {
        switch (queryParam.getOrderType()) {
            case NORMAL:
            case BUSINESS:
            case MEMBER_DETAIL:
                OperationOrderBO operationOrderBO = new OperationOrderBO();
                BeanUtil.copyProperties(queryParam, operationOrderBO);
                return Result.ok(orderService.findByOperationOrderQuery(operationOrderBO));
            case MEMBER:
                OperationMemberOrderBO operationMemberOrderBO = new OperationMemberOrderBO();
                BeanUtil.copyProperties(queryParam, operationMemberOrderBO);
                return Result.ok(memberOrderService.findByOperationMemberOrderBO(operationMemberOrderBO));
            default:
                return null;
        }
    }

    @ApiOperation("更新订单状态")
    @PutMapping("/{orderId}")
    public Result updateStatue(@PathVariable @ApiParam("订单 Id") Integer orderId,
                               @NotNull(message = "订单状态不能为空") @ApiParam("订单状态") @RequestParam OrderStatusEnum status) {
        LogUtil.writeBusinessLog(">>>>>>>>>修改状态>>>>>>>>>");
        LambdaUpdateWrapper<Order> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        lambdaUpdateWrapper.set(Order::getStatus, status.getValue())
                .eq(Order::getId, orderId);
        return Result.save(orderService.update(lambdaUpdateWrapper));
    }


    @ApiOperation("销售利润列表")
    @ApiImplicitParam(name = "storeId", value = "门店ID", paramType = "query")
    @GetMapping("/sales-profitList")
    public Result salesProfitList(Integer storeId,
                                @DateTimeFormat(pattern = "yyyy-MM") Date beginDate,
                                @DateTimeFormat(pattern = "yyyy-MM") Date endDate) {

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(endDate);
        calendar.add(Calendar.MONTH, + 1);
        calendar.add(Calendar.MINUTE, - 1);
        endDate = calendar.getTime();

        List<SalesProfitVo> salesProfitVos = orderService.salesProfit(storeId, beginDate, endDate);

        return Result.ok(salesProfitVos);
    }


    @ApiOperation("销售利润")
    @ApiImplicitParam(name = "storeId", value = "门店ID", paramType = "query")
    @GetMapping("/sales-profit/{storeId}")
    public Result salesProfit(@PathVariable Integer storeId,
                              @DateTimeFormat(pattern = "yyyy-MM") Date beginDate,
                              @DateTimeFormat(pattern = "yyyy-MM") Date endDate) {

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(endDate);
        calendar.add(Calendar.MONTH, + 1);
        calendar.add(Calendar.MINUTE, - 1);
        endDate = calendar.getTime();
        SalesProfitVo salesProfitVo = orderService.salesProfitOne(storeId, beginDate, endDate);
        if (ObjectUtil.isNull(salesProfitVo)){
            return Result.ok(salesProfitVo);
        }

        List<FeesetCostVo> feesetList = orderService.salesFeesetCost(storeId,beginDate, endDate);
        salesProfitVo.setFeesetList(feesetList);

        List<WorkerCostVo> workerCostList = orderService.getWorkerCostVos(storeId,beginDate, endDate);

        Iterator<WorkerCostVo> lista = workerCostList.iterator();
        while (lista .hasNext()){
            WorkerCostVo workerCostVo = lista.next();

            //天数
            workerCostVo.setDays(orderService.getWorkerDay(storeId,workerCostVo.getWorkerId(),beginDate,endDate));
            if (ObjectUtil.isNull(workerCostVo.getDays())) {
                lista.remove();
                continue;
            }
            //差评
            workerCostVo.setBad(orderService.getWorkerBad(storeId,workerCostVo.getWorkerId(),beginDate,endDate));

            workerCostVo.setTurnover(orderService.getTurnoverNum(workerCostVo.getWorkerId(),beginDate,endDate));
            double f =(double)workerCostVo.getTotal()/(double)workerCostVo.getTurnover();
            double commission2 = 80000*f;//800元业绩提成=800*业绩达标率;
            if(commission2>80000){
                commission2=80000;
            }

            if(workerCostVo.getMemberCount()!=null&&workerCostVo.getNormalCount()!=null){
                workerCostVo.setMemberCommission((workerCostVo.getMemberCount()*5+workerCostVo.getNormalCount()*10));//老会员买套餐5元，新会员买套餐10元
            }


            workerCostVo.setCommission(workerCostVo.getBaseSalary() / 26 * workerCostVo.getDays()+(int)commission2/100+ workerCostVo.getMemberCommission()+ workerCostVo.getBad() * 50);
        }


//        for (WorkerCostVo workerCostVo : workerCostList) {
//            workerCostVo.setDays(orderService.getWorkerDay(storeId,workerCostVo.getWorkerId(),beginDate,endDate));
//
//            //差评
//            workerCostVo.setBad(orderService.getWorkerBad(storeId,workerCostVo.getWorkerId(),beginDate,endDate));
//
//            //天数
//            if(workerCostVo.getMemberCount()!=null&&workerCostVo.getNormalCount()!=null){
//                workerCostVo.setMemberCommission((workerCostVo.getMemberCount()*5+workerCostVo.getNormalCount()*10)*100);//老会员买套餐5元，新会员买套餐10元
//            }
//            int dixin = workerCostVo.getBaseSalary() / 26 * workerCostVo.getBad();
//            Integer memberCommission = workerCostVo.getMemberCommission();
//            int badcount = workerCostVo.getBad() * 5000;
//
//            int i = dixin + memberCommission - badcount;
//
//            workerCostVo.setCommission(1);//差评一条扣50元，业绩提成最多800元
//
//        }

        salesProfitVo.setWorkerCostList(workerCostList);

        return Result.ok(salesProfitVo);
    }

    @ApiOperation("人员成本列表")
    @ApiImplicitParam(name = "storeId", value = "门店ID", paramType = "query")
    @GetMapping("/worker-profit/{storeId}")
    public Result workerProfit(@PathVariable Integer storeId,
                              @DateTimeFormat(pattern = "yyyy-MM") Date beginDate,
                              @DateTimeFormat(pattern = "yyyy-MM") Date endDate) {

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(endDate);
        calendar.add(Calendar.MONTH, + 1);
        calendar.add(Calendar.MINUTE, - 1);
        endDate = calendar.getTime();

        SalesProfitVo salesProfitVo = orderService.salesProfitOne(storeId, beginDate, endDate);


        List<FeesetCostVo> feesetList = orderService.salesFeesetCost(storeId,beginDate, endDate);
        salesProfitVo.setFeesetList(feesetList);



        return Result.ok(salesProfitVo);
    }

    @ApiOperation("按月份成本销售额")
    @GetMapping("/salesCost")
    public Result monthSalesCost(Integer storeId,
                                  @DateTimeFormat(pattern = "yyyy-MM") Date beginDate,
                                  @DateTimeFormat(pattern = "yyyy-MM") Date endDate) throws ParseException {


        Calendar calendar = Calendar.getInstance();
        calendar.setTime(endDate);
        calendar.add(Calendar.MONTH, + 1);
        calendar.add(Calendar.MINUTE, - 1);
        endDate = calendar.getTime();

        if(storeId==null) {
            List<String> monthBetweenDate = DateUtil.getMonthBetweenDate(beginDate, endDate);
            if (monthBetweenDate.size() > 0) {
                List<SalesProfitVo> salesProfitVos = new ArrayList<>();
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM");
                for (String s : monthBetweenDate) {
                    try {
                        String key = RedisUtil.getKey("MONTHSALESCOST::" + s);
                        SalesProfitVo salesProfitVo = JsonUtil.fromJson(key, SalesProfitVo.class);
                        if (ObjectUtil.isNotNull(salesProfitVo)) {
                            salesProfitVos.add(salesProfitVo);
                        } else {
                            Date parseStar = simpleDateFormat.parse(s);
                            calendar.setTime(parseStar);
                            calendar.add(Calendar.MONTH, +1);
                            calendar.add(Calendar.MINUTE, -1);
                            Date parseEnd = calendar.getTime();
                            List<SalesProfitVo> salesProfitVos1 = orderService.monthSalesCost(null, parseStar, parseEnd);
                            for (SalesProfitVo sales : salesProfitVos1) {
                                RedisUtil.setKeyTime("MONTHSALESCOST::" + sales.getTime(), 3600, JsonUtil.toJson(sales), DateUnit.SECOND);
                                salesProfitVos.add(sales);
                            }
                        }
                    }catch (Exception e){

                    }
                }
                if(salesProfitVos.size()==monthBetweenDate.size()) {
                    return Result.ok(salesProfitVos);
                }
            }
        }


        List<SalesProfitVo> salesProfitVos = orderService.monthSalesCost(storeId, beginDate, endDate);


        return Result.ok(salesProfitVos);
    }
}